package com.geekhalo.info.domain.info.text;

import com.geekhalo.info.domain.category.InfoCategory;
import com.geekhalo.info.domain.category.exception.InfoCategoryNotFoundException;
import com.geekhalo.info.domain.info.BaseInfo;
import com.geekhalo.info.domain.info.text.create.CreateTextInfoCommand;
import com.geekhalo.info.domain.info.text.create.CreateTextInfoContext;
import com.geekhalo.info.domain.info.text.create.TextInfoCreatedEvent;
import com.geekhalo.info.domain.info.text.offline.OfflineTextInfoContext;
import com.geekhalo.info.domain.info.text.offline.TextInfoOfflinedEvent;
import com.geekhalo.info.domain.info.text.online.OnlineTextInfoContext;
import com.geekhalo.info.domain.info.text.online.TextInfoOnlinedEvent;
import com.geekhalo.info.domain.info.text.update.TextInfoUpdatedEvent;
import com.geekhalo.info.domain.info.text.update.UpdateTextInfoCommand;
import com.geekhalo.info.domain.info.text.update.UpdateTextInfoContext;
import lombok.AccessLevel;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.Setter;

import javax.persistence.*;
import java.util.Optional;

@Entity
@Table(name = "text_info")
@PrimaryKeyJoinColumn(name = "info_id")
@Data
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Setter(AccessLevel.PRIVATE)
public class TextInfo extends BaseInfo {
    private String detail;

    public static TextInfo create(CreateTextInfoContext context) {
        Optional<InfoCategory> categoryOpt = context.getCategory();
        if (!categoryOpt.isPresent()){
            throw new InfoCategoryNotFoundException();
        }
        InfoCategory infoCategory = categoryOpt.get();
        infoCategory.checkCanCreateInfo();

        CreateTextInfoCommand command = context.getCommand();
        TextInfo textInfo = new TextInfo();
        textInfo.setCategoryId(infoCategory.getId());
        textInfo.setTitle(command.getTitle());
        textInfo.setDetail(command.getDetail());
        textInfo.init();
        return textInfo;
    }

    private void init() {
        setOnline();
        addEvent(new TextInfoCreatedEvent(this));
    }

    public void update(UpdateTextInfoContext context) {
        UpdateTextInfoCommand command = context.getCommand();
        setTitle(command.getTitle());
        setDetail(command.getDetail());
        addEvent(new TextInfoUpdatedEvent(this));
    }

    public void online(OnlineTextInfoContext context) {
        if (setOnline()) {
            addEvent(new TextInfoOnlinedEvent(this));
        }
    }

    public void offline(OfflineTextInfoContext context) {
        if (setOffline()) {
            addEvent(new TextInfoOfflinedEvent(this));
        }
    }
}